import axios from "axios";
import { ElMessage } from "element-plus";
import { get, merge } from "lodash-es";
import {
  pendingRequest,
  ev,
  handleSuccessResponse_limit,
  handleErrorResponse_limit,
  generateReqKey,
} from "./responseHandlers.js";

// 白名单
let whiteList = [
  "/manager/system/getDirectoryByTree/staff",
  "/manager/system/getDirectoryByTree"
]


/** 创建请求实例 */
function createService() {
  // 创建一个 axios 实例命名为 service
  const service = axios.create()
  // 请求拦截
  service.interceptors.request.use(
    async (config) => {
      let hash = location.hash;
      // 生成请求Key
      let reqKey = generateReqKey(config, hash);

      if (pendingRequest.has(reqKey)) {
        // 如果是相同请求,在这里将请求挂起，通过发布订阅来为该请求返回结果
        // 这里需注意，拿到结果后，无论成功与否，都需要return Promise.reject()来中断这次请求，否则请求会正常发送至服务器
        let res = null;
        try {
          // 接口成功响应
          res = await new Promise((resolve, reject) => {
            ev.on(reqKey, resolve, reject);
          });
          return Promise.reject({
            type: "limitResSuccess",
            val: res,
          });
        } catch (limitFunErr) {
          // 接口报错
          return Promise.reject({
            type: "limitResError",
            val: limitFunErr,
          });
        }
      } else {
        // 将请求的key保存在config
        config.pendKey = reqKey;
        pendingRequest.add(reqKey);
      }

      // 转换参数为 JSON
      if (config.data) {
        config.data = JSON.stringify(config.data);
      }
      return config
    },
    // 发送失败
    (error) => handleErr(error)
  )
  // 响应拦截（可根据具体业务作出相应的调整）
  service.interceptors.response.use(
    (response) => {
      const apiData = response.data;
      // 统一处理成功响应
      const handleResponse = () => {
        handleSuccessResponse_limit(response);
        return apiData;
      };

      if (whiteList.includes(response.config.url)) {
        return handleResponse();
      }
    //   if (apiData.hasOwnProperty("resultStatus") && apiData?.resultStatus) {
    //     return handleResponse();
    //   }
    //   if (apiData.hasOwnProperty("code") && apiData?.code === 0) {
    //     return handleResponse();
    //   }
      if (Object.hasOwn(apiData, "resultStatus") && apiData?.resultStatus) {
        return handleResponse();
      }
      if (Object.hasOwn(apiData, "code") && apiData?.code === 200) {
        return handleResponse();
      }
      const errorCode = apiData.errorCode || apiData.errCode;
      switch (errorCode) {
        case 401:
        case '020030':
          // Token 过期时
          return ElMessage.error("会话已超时，请重新进入");
        default:
          // 不是正确的 code
          if (apiData?.errorMessage && !response.config.noToast) {
            ElMessage.error(apiData.errorMessage)
          }
          if (apiData?.message && !response.config.noToast) {
            ElMessage.error(apiData.message)
          }
          return handleResponse();
      }
    },
    (error) => {
      // status 是 HTTP 状态码
      const status = get(error, "response.status")
      console.log("error", error)
      console.log("status", status)
      switch (status) {
        case 400:
          error.message = "请求错误"
          break
        case 401:
          // Token 过期时
          error.message = "会话已超时，请重新进入"
          break
        case 403:
          error.message = "拒绝访问"
          break
        case 404:
          error.message = "请求地址出错"
          break
        case 408:
          error.message = "请求超时"
          break
        case 500:
          error.message = "服务器内部错误"
          break
        case 501:
          error.message = "服务未实现"
          break
        case 502:
          error.message = "网关错误"
          break
        case 503:
          error.message = "服务不可用"
          break
        case 504:
          error.message = "网关超时"
          break
        case 505:
          error.message = "HTTP 版本不受支持"
          break
        default:
          break
      }
      if (error.message) {
        ElMessage.error(error.message)
      }
      return handleErr(error)
      // return Promise.resolve({ code: status, message: error.message }); // 返回一个 resolved 的 Promise，避免错误冒泡
    }
  )
  return service
}

function handleErr(error) {
  // 超时错误处理
  if (JSON.stringify(error).indexOf("600000ms") !== -1) {
    ElMessage.error("请求超时！");
    handleErrorResponse_limit(error);
    // return Promise.reject(error);
    return Promise.resolve({ code: 408, message: "请求超时" }); // 返回 resolved，避免错误冒泡
  }

  // 通用错误处理
  handleErrorResponse_limit(error);
  // return Promise.reject(error);
  return Promise.resolve({ code: 500, message: "请求失败，请稍后重试" }); // 返回 resolved，避免错误冒泡
}


/** 创建请求方法 */
function createRequest(service) {
  return function (config) {
    const token = ""
    const defaultConfig = {
      headers: {
        // 携带 Token
        'Content-Type': 'application/json;chartset=utf-8',
        'token': token,
      },
      timeout: 60000,
      // baseURL: '/amsp' || '/flow',  
      data: {}
    }


    // 根据请求的 URL 来动态设置 baseURL
    let baseURL;
    if (config.url && config.url.startsWith('/amsp')) {
      baseURL = '/amsp';
    } else if (config.url && config.url.startsWith('/flow')) {
      baseURL = '/flow';
    }else if (config.url && config.url.startsWith('/oaApi')) {
      baseURL = '/oaApi';
    }
    
    // 如果没有匹配到，则使用默认值或者抛出错误，这里使用默认值为空字符串
    if (!baseURL) {
      baseURL = '';
    }

    defaultConfig.baseURL = baseURL;


    // 将默认配置 defaultConfig 和传入的自定义配置 config 进行合并成为 mergeConfig
    const mergeConfig = merge(defaultConfig, config)
    return service(mergeConfig)
  }
}

/** 用于网络请求的实例 */
const service = createService()
/** 用于网络请求的方法 */
export const request = createRequest(service)
